home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 27 / CU Amiga Magazine's Super CD-ROM 27 (1998)(EMAP Images)(GB)[!][issue 1998-10].iso / CUCD / Programming / FreshBar / Source / Bar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-15  |  11.1 KB  |  488 lines

  1. //*************************************************************************//
  2. // Filename:    Bar.cpp
  3. // Autor:       Christian Taulien of Strange Intelligence
  4. // Purpose:     Bar management and display implementation for FreshBar
  5. // Creation:    17. Mai 1998
  6. //*************************************************************************//
  7.  
  8. #include "global.h"
  9. #include "Bar.h"
  10. #include "WindowList.h"
  11. #include "TextMeasure.h"
  12. #include "VisualInfo.h"
  13.  
  14. #include <clib/exec_protos.h>
  15. #include <clib/gadtools_protos.h>
  16. #include <clib/graphics_protos.h>
  17.  
  18. #include <graphics/rastport.h>
  19.  
  20. extern "C" void NewList(struct List *list);
  21.  
  22. //******************************************************************//
  23. //******************************************************************//
  24. //
  25. //  BarNodeC
  26. //
  27. //******************************************************************//
  28. //******************************************************************//
  29. ULONG BarNodeC::m_ulNextFreeID = 0;
  30.  
  31. BarNodeC::BarNodeC(BarListC *arg_poBarList, char *arg_sName, ULONG arg_ulMaxValue)
  32. /*S*/
  33. {
  34.   TRACE("Konstruktor");
  35.   if (!arg_poBarList)
  36.   {
  37.     TRACE("Falscher Parameter!");
  38.     throw;
  39.   } // if
  40.  
  41.   // init the baseclassmembers
  42.   ln_Succ       = NULL;
  43.   ln_Pred       = NULL;
  44.   ln_Type       = NT_USER;
  45.   ln_Pri        = 0;
  46.  
  47.   // now our members
  48.   m_oName = arg_sName;
  49.   m_ulMaxValue = arg_ulMaxValue;
  50.   m_ulCurrentValue = 0;
  51.   m_bShowPercent = FALSE;
  52.   m_ulID = ++m_ulNextFreeID;
  53.   m_iPen = 3;
  54.   m_iBPen = 0;
  55.   m_eProgressMode = PM_Percent;
  56.  
  57.   AddTail(arg_poBarList, this);
  58. } // BarNodeC::BarNodeC()
  59. /*E*/
  60. BarNodeC::~BarNodeC()
  61. /*S*/
  62. {
  63.   TRACE("Destruktor");
  64.  
  65.   // delete the name
  66.   if (ln_Name)
  67.   {
  68.     delete ln_Name;
  69.   } // if
  70.  
  71.   // if the node is in a list
  72.   if (ln_Pred && ln_Succ)
  73.   {
  74.     Remove(this);
  75.   } // if
  76. }
  77. /*E*/
  78. BarNodeC *BarNodeC::getNext(void)
  79. /*S*/
  80. {
  81.   TRACE("getNext()");
  82.   if (ln_Succ && ln_Succ->ln_Succ)
  83.   {
  84.     return (BarNodeC *) ln_Succ;
  85.   } // if
  86.  
  87. return NULL;
  88. }
  89. /*E*/
  90. BarNodeC *BarNodeC::getPrev(void)
  91. /*S*/
  92. {
  93.   TRACE("getPrev()");
  94.   if (ln_Pred && ln_Pred->ln_Pred)
  95.   {
  96.     return (BarNodeC *) ln_Pred;
  97.   } // if
  98.  
  99. return NULL;
  100. }
  101. /*E*/
  102. void BarNodeC::drawBar(BarWindowNodeC *arg_poBWNode,
  103.                        TextMeasureC *arg_poTeMe,
  104.                        ULONG arg_ulPosX,
  105.                        ULONG arg_ulPosY,
  106.                        ULONG arg_ulBarBreite,
  107.                        ULONG arg_ulBreite,
  108.                        ULONG arg_ulHoehe)
  109. /*S*/
  110.   TRACE("Entry");
  111.   struct RastPort *poRPort = arg_poBWNode->getWindow()->RPort;
  112.   VisualInfoC oVI(arg_poBWNode->getWindow());
  113.   if (oVI.isOk())
  114.   {
  115.     TRACE("Visualinfo ok");
  116.  
  117.     // Bar-Title ausgeben
  118.     SetAPen(poRPort, 1);
  119.     Move(poRPort, arg_ulPosX, arg_ulPosY+arg_ulHoehe-5);
  120.     Text(poRPort, (char *) m_oName, m_oName.getLength());
  121.  
  122.     int iPosX = arg_ulPosX + arg_ulBreite - arg_ulBarBreite;
  123.     DrawBevelBox( poRPort,
  124.                   iPosX,
  125.                   arg_ulPosY,
  126.                   arg_ulBarBreite,
  127.                   arg_ulHoehe,
  128.                   GT_VisualInfo, (APTR) oVI,
  129.                   GTBB_Recessed, TRUE,
  130.                   TAG_DONE );
  131.  
  132.     fillBar(poRPort,
  133.             arg_poTeMe,
  134.             arg_ulPosX,
  135.             arg_ulPosY,
  136.             arg_ulBarBreite,
  137.             arg_ulBreite,
  138.             arg_ulHoehe);
  139.   } // if
  140. }
  141. /*E*/
  142. void BarNodeC::fillBar(struct RastPort *arg_poRPort,
  143.                        TextMeasureC *arg_poTeMe,
  144.                        ULONG arg_ulPosX,
  145.                        ULONG arg_ulPosY,
  146.                        ULONG arg_ulBarBreite,
  147.                        ULONG arg_ulBreite,
  148.                        ULONG arg_ulHoehe)
  149. /*S*/
  150. {
  151.   TRACE("Entry");
  152.   arg_ulPosX++;
  153.   arg_ulPosY++;
  154.   arg_ulBreite-=2;
  155.   arg_ulHoehe-=3;
  156.   arg_ulBarBreite-=3;
  157.  
  158.   // der CurrentValuef dar nicht kleiner als null sein
  159.   if (((int ) m_ulCurrentValue) < 0) m_ulCurrentValue = 0;
  160.   if (m_ulCurrentValue > m_ulMaxValue) m_ulCurrentValue = m_ulMaxValue;
  161.  
  162.   // Breite des blauen streifens berechnen
  163.   int iBreite = arg_ulBarBreite;
  164.   if (m_ulMaxValue)
  165.   {
  166.     iBreite = (arg_ulBarBreite*m_ulCurrentValue)/m_ulMaxValue;
  167.   } // if
  168.  
  169.   int iPosX = arg_ulPosX + arg_ulBreite - arg_ulBarBreite - 1;
  170.   SetAPen(arg_poRPort, m_iPen);
  171.   SetDrMd(arg_poRPort, JAM2);
  172.   RectFill(arg_poRPort,
  173.            iPosX,
  174.            arg_ulPosY,
  175.            iPosX + iBreite,
  176.            arg_ulPosY + arg_ulHoehe);
  177.  
  178.   if (iBreite!=arg_ulBarBreite)
  179.   {
  180.     SetAPen(arg_poRPort, m_iBPen);
  181.     RectFill(arg_poRPort,
  182.              iPosX + iBreite,
  183.              arg_ulPosY,
  184.              iPosX + arg_ulBarBreite,
  185.              arg_ulPosY + arg_ulHoehe);
  186.   } // if
  187.  
  188.   // nun den text ausgeben
  189.   SetAPen(arg_poRPort, 2);
  190.   SetDrMd(arg_poRPort, JAM1);
  191.   switch (m_eProgressMode)
  192.   {
  193.     case PM_Percent:
  194.       { // dummy scope
  195.         int iPercent = (m_ulCurrentValue * 100) / m_ulMaxValue;
  196.         StringC oBuf(10);
  197.         oBuf.formatString("%d%%", iPercent);
  198.         Move(arg_poRPort, iPosX + (arg_ulBarBreite-arg_poTeMe->getTextWidth(oBuf))/2, arg_ulPosY + arg_ulHoehe - 2);
  199.         Text(arg_poRPort, (char *) oBuf, oBuf.getLength());
  200.       } // dummy scope
  201.       break;
  202.     case PM_Absolute:
  203.       { // dummy scope
  204.         StringC oBuf(30);
  205.         oBuf.formatString("%d/%d", m_ulCurrentValue, m_ulMaxValue);
  206.         Move(arg_poRPort, iPosX + (arg_ulBarBreite-arg_poTeMe->getTextWidth(oBuf))/2, arg_ulPosY + arg_ulHoehe - 2);
  207.         Text(arg_poRPort, (char *) oBuf, oBuf.getLength());
  208.       } // dummy scope
  209.       break;
  210.   } // switch
  211. }
  212. /*E*/
  213.  
  214. //******************************************************************//
  215. //******************************************************************//
  216. //
  217. //  BarListC
  218. //
  219. //******************************************************************//
  220. //******************************************************************//
  221. BarListC::BarListC()
  222. /*S*/
  223. {
  224.   TRACE("Konstruktor");
  225.   NewList(this);
  226.   m_iBarWidth = 50;
  227. } // BarListC::BarListC()
  228. /*E*/
  229. BarListC::~BarListC()
  230. /*S*/
  231. {
  232.   TRACE("Destruktor");
  233.   removeAll();
  234.  
  235. } // BarListC::~FLXWacthListC()
  236. /*E*/
  237. void BarListC::removeAll()
  238. /*S*/
  239. {
  240.   TRACE("Entry");
  241.   // wenn die Liste nicht leer ist
  242.   if (!IsListEmpty(this))
  243.   {
  244.     BarNodeC *poNode;
  245.     while (poNode = (BarNodeC *) RemHead(this))
  246.     {
  247.       // Vorgaenger und Nachfolger auf null setzen
  248.       // weil mit RemHead schon removed und der Destruktor
  249.       // das bei nicht nulligen nodes nochmal machen wuerde.
  250.       poNode->ln_Succ = NULL;
  251.       poNode->ln_Pred = NULL;
  252.  
  253.       delete poNode;
  254.     } // while
  255.   } // if
  256.   NewList(this);
  257. }
  258. /*E*/
  259. void  BarListC::removeBar(ULONG arg_ulBarID)
  260. /*S*/
  261. {
  262.   TRACE("Entry");
  263.   // just find the node an delete it
  264.   BarNodeC *poNode = findBarNode(arg_ulBarID);
  265.   if (poNode)
  266.   {
  267.     delete poNode;
  268.   } // if
  269. }
  270. /*E*/
  271. BarNodeC *BarListC::addBar(char *arg_sName, ULONG arg_ulMaxValue)
  272. /*S*/
  273. {
  274.   TRACE("Entry");
  275.  
  276.   // neuen Balken erzeugen
  277.   BarNodeC *poNode = new BarNodeC(this, arg_sName, arg_ulMaxValue);
  278.   if (!poNode)
  279.   {
  280.     TRACE("Kein Speicher");
  281.     return FALSE;
  282.   } // if
  283. return poNode;
  284. }
  285. /*E*/
  286. BarNodeC *BarListC::findBarNode(ULONG arg_ulBarID)
  287. /*S*/
  288. {
  289.   TRACE("Entry");
  290.   BarNodeC *pNode = NULL;
  291.  
  292.   // wenn die Balkenliste nicht leer ist
  293.   if (!IsListEmpty(this))
  294.   {
  295.     pNode = (BarNodeC *) lh_Head;
  296.     do
  297.     {
  298.       if (pNode->m_ulID == arg_ulBarID)
  299.       {
  300.         return pNode;
  301.       } // if
  302.     } while (pNode = pNode->getNext());
  303.   } // if
  304.  
  305. return pNode;
  306. }
  307. /*E*/
  308. int BarListC::indexOf(BarNodeC *arg_pNode)
  309. /*S*/
  310. {
  311.   TRACE("Entry");
  312.  
  313.   // wenn die Balkenliste nicht leer ist
  314.   if (arg_pNode && !IsListEmpty(this))
  315.   {
  316.     int iIndex = 0;
  317.  
  318.     // hole 1. eintrag
  319.     BarNodeC *pNode = (BarNodeC *) lh_Head;
  320.     do
  321.     {
  322.       // wenn gefunden
  323.       if (pNode==arg_pNode)
  324.       {
  325.         return iIndex;
  326.       } // if
  327.  
  328.       iIndex++;
  329.     } while (pNode = pNode->getNext());
  330.   } // if
  331.  
  332. return -1;
  333. }
  334. /*E*/
  335. BarNodeC *BarListC::operator[](int arg_iIndex)
  336. /*S*/
  337. {
  338.   TRACE("ENTRY");
  339.  
  340.   BarNodeC *pNode = NULL;
  341.  
  342.   // wenn die Balken nicht leer ist
  343.   if (!IsListEmpty(this))
  344.   {
  345.     int index = 0;
  346.  
  347.     // hole 1. eintrag
  348.     pNode = (BarNodeC *) lh_Head;
  349.     do
  350.     {
  351.       // wenn i.ten eintrag erreicht
  352.       if (index == arg_iIndex)
  353.       {
  354.         return pNode;
  355.       } // if
  356.  
  357.       index++;
  358.     } while (pNode = pNode->getNext());
  359.   } // if
  360.  
  361. return pNode;
  362. }
  363. /*E*/
  364. int BarListC::getSize(void)
  365. /*S*/
  366. {
  367.   TRACE("Entry");
  368.   int iSize = 0;
  369.  
  370.   // wenn die Liste nicht leer ist
  371.   if (!IsListEmpty(this))
  372.   {
  373.     // hole 1. Eintrag
  374.     BarNodeC *pNode = (BarNodeC *) lh_Head;
  375.     for (iSize=1; pNode = pNode->getNext(); iSize++);
  376.   } // if
  377.  
  378. return iSize;
  379. }
  380. /*E*/
  381. int BarListC::getHeight(struct Screen *arg_poScreen)
  382. /*S*/
  383. {
  384.   TRACE("Entry");
  385.   // Objekt zum ermitteln der Text-hoehe
  386.   TextMeasureC oTeMe(arg_poScreen);
  387.  
  388. return getSize()*(oTeMe.getTextHeight()+7);
  389. }
  390. /*E*/
  391. int BarListC::getBarTitleWidth(struct Screen *arg_poScreen)
  392. /*S*/
  393. {
  394.   TRACE("Entry");
  395.   int iMaxWidth = 0;
  396.  
  397.   TextMeasureC oTeMe(arg_poScreen);
  398.  
  399.   // wenn die Liste nicht leer ist
  400.   if (!IsListEmpty(this))
  401.   {
  402.     // hole 1. Eintrag
  403.     BarNodeC *pNode = (BarNodeC *) lh_Head;
  404.  
  405.     do
  406.     {
  407.       iMaxWidth = SIFC_MAX(iMaxWidth, oTeMe.getTextWidth(pNode->getName()));
  408.     } while (pNode = pNode->getNext());
  409.   } // if
  410. return iMaxWidth+5;
  411. }
  412. /*E*/
  413. int BarListC::getWidth(struct Screen *arg_poScreen)
  414. /*S*/
  415. {
  416.   TRACE("Entry");
  417. return getBarTitleWidth(arg_poScreen) + m_iBarWidth;
  418. }
  419. /*E*/
  420. void BarListC::drawBars(BarWindowNodeC *arg_poBWNode, ULONG arg_ulPosX, ULONG arg_ulPosY)
  421. /*S*/
  422.   TRACE("Entry");
  423.   struct Window *poWindow = arg_poBWNode->getWindow();
  424.  
  425.   TextMeasureC oTeMe(poWindow->WScreen);
  426.   int iHoehe = oTeMe.getTextHeight()+6;
  427.   int iBreite = getWidth(poWindow->WScreen);
  428.  
  429.   struct TextFont *poTextFont = OpenFont(poWindow->WScreen->Font); // font oeffne
  430.   struct TextFont *poOldTextFont = poWindow->RPort->Font; // alten sichern
  431.   SetFont(poWindow->RPort, poTextFont); // neuen einstellen
  432.  
  433.   for (int i=0; i<getSize();i++)
  434.   { 
  435.     BarNodeC *poBarNode = operator[](i);
  436.     if (poBarNode)
  437.     {
  438.       poBarNode->drawBar(arg_poBWNode,
  439.                          &oTeMe,
  440.                          arg_ulPosX,
  441.                          arg_ulPosY+i*iHoehe,
  442.                          m_iBarWidth,
  443.                          iBreite,
  444.                          iHoehe-4);
  445.     } // if
  446.   } // for
  447.  
  448.   SetFont(poWindow->RPort, poOldTextFont);
  449.   CloseFont(poTextFont);
  450. }
  451. /*E*/
  452. void BarListC::fillBars(BarWindowNodeC *arg_poBWNode, ULONG arg_ulPosX, ULONG arg_ulPosY)
  453. /*S*/
  454. {
  455.   TRACE("Entry");
  456.   struct Window *poWindow = arg_poBWNode->getWindow();
  457.  
  458.   TextMeasureC oTeMe(poWindow->WScreen);
  459.   int iHoehe = oTeMe.getTextHeight()+6;
  460.   int iBreite = getWidth(poWindow->WScreen);
  461.  
  462.   struct TextFont *poTextFont = OpenFont(poWindow->WScreen->Font); // font oeffne
  463.   struct TextFont *poOldTextFont = poWindow->RPort->Font; // alten sichern
  464.   SetFont(poWindow->RPort, poTextFont); // neuen einstellen
  465.  
  466.   for (int i=0; i<getSize();i++)
  467.   {
  468.     BarNodeC *poBarNode = operator[](i);
  469.     if (poBarNode)
  470.     {
  471.       poBarNode->fillBar(poWindow->RPort,
  472.                          &oTeMe,
  473.                          arg_ulPosX,
  474.                          arg_ulPosY+i*iHoehe,
  475.                          m_iBarWidth,
  476.                          iBreite,
  477.                          iHoehe-4);
  478.     } // if
  479.   } // for
  480.  
  481.   SetFont(poWindow->RPort, poOldTextFont);
  482.   CloseFont(poTextFont);
  483. }
  484. /*E*/
  485.  
  486.